home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-03 | 7.2 KB | 270 lines | [TEXT/MPS ] |
- //----------------------------------------------------------------------------------------
- // UPatch.cp
- // Copyright © 1985-96 by Apple Computer, Inc. All rights reserved.
- //----------------------------------------------------------------------------------------
-
- #ifndef __UPATCH__
- #include "UPatch.h"
- #endif
-
- // MacApp
-
- #ifndef __UFAILURE__
- #include "UFailure.h"
- #endif
-
- #ifndef __UCOREUTILITIES__
- #include "UCoreUtilities.h"
- #endif
-
- #ifndef __UMEMORY__
- #include "UMemory.h"
- #endif
-
- // Toolbox
-
- #if qPowerPC
- #ifndef __FRAGLOAD__
- #include <FragLoad.h>
- #endif
- #endif
-
- #ifndef __GESTALTEQU__
- #include <GestaltEqu.h>
- #endif
-
- #ifndef __LOWMEM__
- #include <LowMem.h>
- #endif
-
- #ifndef __MEMORY__
- #include <Memory.h>
- #endif
-
- #ifndef __OSUTILS__
- #include <OSUtils.h>
- #endif
-
- #if qPowerPC
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
- #endif
-
- #ifndef __TEXTEDIT__
- #include <TextEdit.h>
- #endif
-
- #ifndef __TRAPS__
- #include <Traps.h>
- #endif
-
- // ANSI
-
- #ifndef __STDIO__
- #include <stdio.h>
- #endif
-
- //----------------------------------------------------------------------------------------
-
- TrapPatchPtr TrapPatch::pPatchList; // global allocation declared in my header
-
- //----------------------------------------------------------------------------------------
- // PatchTrap:
- //----------------------------------------------------------------------------------------
- #pragma segment MAPatchRes
-
- TrapPatch::TrapPatch()
- {
- trapNum = 0;
- oldTrapAddr = NULL;
- patchRoutine = NULL;
- nextPatch = NULL;
- }
-
- //----------------------------------------------------------------------------------------
- // PatchTrap:
- //----------------------------------------------------------------------------------------
- #pragma segment MAPatchRes
-
- short TrapPatch::PatchTrap(short theTrapNum, void* theRoutine)
- {
- LookupOldTrapAddress(theTrapNum);
- trapNum = theTrapNum;
- nextPatch = pPatchList;
- pPatchList = this;
- NSetTrapAddress((UniversalProcPtr)theRoutine, theTrapNum, GetTrapType(theTrapNum));
- return noErr;
- } // PatchTrap
-
- //----------------------------------------------------------------------------------------
- // LookupOldTrapAddress:
- //----------------------------------------------------------------------------------------
- #pragma segment MAPatchRes
-
- void TrapPatch::LookupOldTrapAddress(short theTrapNum)
- {
- oldTrapAddr = NGetTrapAddress(theTrapNum, GetTrapType(theTrapNum));
- } // LookupOldTrapAddress
-
- //----------------------------------------------------------------------------------------
- // GetPreviousPatchPtr: walks the patch list backwards to return the patch record just
- // prior to (*thePatchPtr) in the patch list
- //----------------------------------------------------------------------------------------
- #pragma segment MAPatchRes
-
- TrapPatchPtr TrapPatch::GetPreviousPatchPtr(void)
- {
- TrapPatchPtr tempPatchPtr = pPatchList;
-
- if (tempPatchPtr == this)
- return NULL;
- while ((tempPatchPtr != NULL) && (tempPatchPtr->nextPatch != this))
- tempPatchPtr = tempPatchPtr->nextPatch;
- return tempPatchPtr;
- } // GetPreviousPatchPtr
-
- //----------------------------------------------------------------------------------------
- // GetNewerPatchPtr: returns a newer patch record in the patch list which has the *same*
- // trapNum as thePatch
- //----------------------------------------------------------------------------------------
- #pragma segment MAPatchRes
-
- TrapPatchPtr TrapPatch::GetNewerPatchPtr(void)
- {
- TrapPatchPtr newerPatch = NULL;
- TrapPatchPtr tempPatchPtr = pPatchList;
-
- while ((tempPatchPtr != NULL) && (tempPatchPtr != this))
- {
- if (tempPatchPtr->trapNum == trapNum)
- newerPatch = tempPatchPtr;
- tempPatchPtr = tempPatchPtr->nextPatch;
- }
- return newerPatch;
- } // GetNewerPatchPtr
-
-
- //----------------------------------------------------------------------------------------
- // UnpatchTrap:
- //----------------------------------------------------------------------------------------
- #pragma segment MAPatchRes
-
- void TrapPatch::UnpatchTrap(void)
- {
- // You can't patch nothing, so we use the old trap address to keep track of if we
- // have a patch installed.
- if (oldTrapAddr == NULL)
- return;
-
- // If this trap has a newer patch than the patch we're removing, then we have to take
- // some extra special precautions. We have to muck with that patch's oldTrapAddr to
- // point to this patch record's oldTrapAddr. We can pretty well ignore the case of
- // an older patch on this same trap since the trapaddress in our patch record will
- // be correct.
-
- // only set the trap address if there *isn't* a newer patch
- TrapPatchPtr newerPatchPtr = GetNewerPatchPtr();
- if (newerPatchPtr == NULL)
- NSetTrapAddress(oldTrapAddr, trapNum, GetTrapType(trapNum));
- else
- {
- // set up newerPatchPtr patch record so that it points to thePatch's OldTrapAddr
- newerPatchPtr->oldTrapAddr = oldTrapAddr;
- }
- oldTrapAddr = NULL;
-
- if (patchRoutine)
- {
- DisposeRoutineDescriptor(patchRoutine);
- patchRoutine = NULL;
- }
-
- // Unlink the patch from the linked list of patches
- if (this == pPatchList)
- pPatchList = nextPatch;
- else
- {
- TrapPatchPtr aPatchPtr = GetPreviousPatchPtr();
- if (aPatchPtr != NULL) // Couldn't find thePatch, don't unpatch it
- aPatchPtr->nextPatch = nextPatch;
- }
- nextPatch = NULL;
-
- } // UnpatchTrap
-
- //----------------------------------------------------------------------------------------
- // FlushCache:
- //----------------------------------------------------------------------------------------
- #pragma segment MAPatchRes
-
- void FlushCache()
- {
- #if !qPowerPC
- // Flush the instruction and data cache, if traps are enabled.
- long OldA5 = SetCurrentA5(); // ***** May be called from trap patches *****
- if (TrapExists(_HWPriv))
- {
- FlushDataCache();
- FlushInstructionCache();
- }
- SetA5(OldA5);
- #endif
- } // FlushCache
-
- #if !qPowerPC
- //----------------------------------------------------------------------------------------
- // PatchJmpInstruction:
- //----------------------------------------------------------------------------------------
- #pragma segment MAPatchRes
-
- void PatchJmpInstruction(void* patchAddress, void* jumpAddress)
- {
- JmpInstructionTemplate* aJmpInstructionPtr = (JmpInstructionTemplate *) patchAddress;
- aJmpInstructionPtr->Jmp = 0x4EF9;
- aJmpInstructionPtr->Routine = jumpAddress;
-
- FlushCache();
- } // PatchJmpInstruction
-
- #endif
-
- //----------------------------------------------------------------------------------------
- // UnpatchAll:
- //----------------------------------------------------------------------------------------
- #pragma segment MAPatchRes
-
- void TrapPatch::UnpatchAll(void)
- {
- while (pPatchList != NULL)
- {
- pPatchList->UnpatchTrap();
- }
- }
-
-
- #if !qPowerPC
- //----------------------------------------------------------------------------------------
- // SetCallBack:
- //----------------------------------------------------------------------------------------
- #pragma segment MAPatchRes
-
- void SetCallBack(void* targProc, long itsRefCon, CallBackPtr theCallBackPtr)
- {
- theCallBackPtr->saveRtnAdd = 0x2F17;
- theCallBackPtr->moveRefCon = 0x2F7C;
- theCallBackPtr->refCon = itsRefCon;
- theCallBackPtr->targOffset = 0x0004;
- theCallBackPtr->jmpInst = 0x4EF9;
- theCallBackPtr->jmpTarg = targProc;
-
- FlushCache();
- } // SetCallBack
-
- #endif
-
- //----------------------------------------------------------------------------------------
- // End of UPatch.cp
-
- #pragma segment Inline
-